import logging
import snakemq.link as slink
import snakemq.packeter as spacketer
import snakemq.messaging as smessaging
import snakemq.message as smessage
import datetime
import json

import Tkinter
from Tkinter import Tk
import threading

# NurseStation
#
# Nurses' station interface from which
# the vital signs of all patients can 
# be monitored.
class NurseStation(Tkinter.Frame):

	_id_prefix = "NURSE"

	def __init__(self, master, id, title="", host="localhost"):
		Tkinter.Frame.__init__(self, master)

		self.id = self._id_prefix + "_" + str(id)

		# configure message queue
		self.host = host
		self.link = slink.Link()
		self.packeter = spacketer.Packeter(self.link)
		self.messaging = smessaging.Messaging(self.id, "", self.packeter)
		self.messaging.on_message_recv.add(self.recv)
		self.collector_ids = []
		self.alarm_ids = []
		self.sensors = {}
		self.messages_recvd = 0;

		# setup grid
		self.grid(column=0, row=0, sticky=(Tkinter.N, Tkinter.W, Tkinter.E, Tkinter.S))
		self.columnconfigure(0, weight=1)
		self.rowconfigure(0, weight=1)
		self.open_row = 1 # first unpopulated row

	# start listening on a port
	def addListener(self, port):
		print "Added listener on port %d." % port
		self.link.add_listener(("", port))

	# open outgoing channel on a port
	def addConnector(self, port):
		print "Added connector on port %d." % port
		self.link.add_connector((self.host, port))

	# message receipt callback
	def recv(self, conn, id, msg):
		self.messages_recvd += 1
		print datetime.datetime.now().isoformat(), str(self.messages_recvd)
		message_data = json.loads(msg.data)
		if id.startswith("COLLECTOR") and message_data["command"] == "REGISTER":
			self.subscribeCollector(id, message_data)
		if id.startswith("COLLECTOR") and message_data["command"] == "UPDATE":
			self.updateVitals(id, message_data)

		if id.startswith("ALARMS") and message_data["command"] == "REGISTER":
			self.subscribeAlarms(id, message_data)
		if id.startswith("ALARMS") and message_data["command"] == "UPDATE":
			self.updateAlarms(id, message_data)

	# subscribe to a data collector, building out
	# the readouts for each sensor.
	def subscribeCollector(self, id, message_data):
		self.collector_ids.append(id)
		Tkinter.Label(text="Sensor Group %s" % id).grid(column=1, row=self.open_row, sticky=Tkinter.W)
		self.open_row += 1
		for sensor in message_data["sensors"]:
			self.sensors[sensor["name"]] = sensor
			self.sensors[sensor["name"]]["label"] = Tkinter.StringVar()
			self.sensors[sensor["name"]]["label"].set(str(sensor["level"]))
			Tkinter.Label(text="Sensor: %s" % sensor["name"]).grid(column=1, row=self.open_row, sticky=Tkinter.W)
			Tkinter.Label(textvariable=self.sensors[sensor["name"]]["label"]).grid(column=2, row=self.open_row, sticky=Tkinter.W)
			self.open_row += 1

	def updateVitals(self, id, message_data):
		for sensor in message_data["sensors"]:
			if self.sensors.has_key(sensor["name"]):
				self.sensors[sensor["name"]]["label"].set(str(sensor["level"]))

	def subscribeAlarms(self, id, message_data):
		self.alarm_ids.append(id)

	def updateAlarms(self, id, message_data):
		for alarm in message_data["alarms"]:
			if self.sensors.has_key(alarm["name"]):
				self.sensors[alarm["name"]]["label"].set("WARNING")

	def start(self):
		threading.Thread(target=self.link.loop).start()
		print "Started UI listener loop"